//
//  WmcDecibeManager.swift
//  YPWatermarkCamera
//
//  Created by 赵新 on 2022/7/21.
//

import AVFAudio
import UIKit

class WmcDecibeManager: NSObject {
    // Public

    /// 单例实例化
    public static let shared: WmcDecibeManager = {
        let manager = WmcDecibeManager()
        return manager
    }()

    // Internal

    /// 计时器
    var timer: Timer?

    /// 分贝
    let decibeRelay: BehaviorRelay<Double> = .init(value: 0)

    /// 当前记录器
    var currentAudioRecorder: AVAudioRecorder?

    /// 秒计数器
    var secondCount = 0

    /// 最大秒计数器
    var maxSecondCount = 500

    /// 存储地址
    var saveUrl: URL {
        return URL(fileURLWithPath: "\(NSTemporaryDirectory())/noise_recording.m4a")
    }

    /// 配置
    func config() {}

    /// 开始分贝更新
    func start() {
        log("开始分贝更新")
        return; // 停用分贝
        let recordingSession = AVAudioSession.sharedInstance()
        do {
            try recordingSession.setCategory(.playAndRecord)
            try recordingSession.setActive(true)

            recordingSession.requestRecordPermission { result in
                guard result else { return }
            }
            /// 权限检查
            let microphoneStauts = WmcAuthorizedManager.microphone()
            if microphoneStauts.info.isAvailable {
                // 开始采集
                captureAudio()
            }
        } catch let err {
            log("音频采集: 创建 recordSession 失败 \(err)")
        }
    }

    /// 停止分贝更新
    func stop() {
        log("停止分贝更新")
        currentAudioRecorder?.stop()
        currentAudioRecorder = nil
        stopTimer()
        try? FileManager.default.removeItem(at: saveUrl)
    }

    /// 开始采集
    func captureAudio() {
        log("开始音频采集")
        // 临时写入路径
        let url = saveUrl
        let settings = [
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVSampleRateKey: 16000,
            AVNumberOfChannelsKey: 1,
            AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue,
        ]

        try? FileManager.default.removeItem(at: url)
        do {
            currentAudioRecorder = try .init(url: url, settings: settings)
            currentAudioRecorder?.record()
            currentAudioRecorder?.isMeteringEnabled = true
            // 开启计时器更新
            startTimer()
        } catch let err {
            log("音频采集: 开始录音recording处理失败 \(err)")
        }
    }

    @objc
    func updateNoise() {
        if secondCount > maxSecondCount { // 超出计数器
            stop() // 停止
            captureAudio() // 重新开始采集
            secondCount = 0 // 重置计数器
        }
        guard let currentAudioRecorder = currentAudioRecorder else {
            stopTimer()
            return
        }
        currentAudioRecorder.updateMeters()
        let db = currentAudioRecorder.averagePower(forChannel: 0)
        decibeRelay.accept(Double(db))
        secondCount += 1
    }

    // Fileprivate

    /// 日志系统
    fileprivate func log(_ log: String) {
        WmcLogManager.DebugLog(type: .decibeManager, log: log)
    }

    // Private

    private func startTimer() {
        stopTimer()
        timer = .scheduledTimer(timeInterval: 1,
                                target: self,
                                selector: #selector(self.updateNoise),
                                userInfo: nil,
                                repeats: true)
    }

    private func stopTimer() {
        timer?.invalidate()
        timer = nil
    }
}
